﻿using AutoMapper;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Mysoft.AppStartup.Container;
using Mysoft.Common.Configuration;
using Mysoft.Core.Filters;
using Mysoft.Data.DBContext;
using Mysoft.Data.UserManager;
using Mysoft.Tasks.Queue.IService;
using Mysoft.Tasks.Queue.RabbitMQ.Extensions;
using Mysoft.Tasks.Queue.RedisMQ.Extensions;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System.Reflection;

namespace Mysoft.AppStartup.Startup
{
    /// <summary>
    /// IServiceCollection扩展
    /// </summary>
    public static class ContainerModuleExtension
    {
        /// <summary>
        /// 注册服务
        /// </summary>
        /// <param name=""></param>
        /// <returns></returns>
        public static IServiceCollection AddModule(this IServiceCollection services, IConfiguration configuration)
        {
            AddHttpContext(services);
            AddUserContext(services);
            AddCors(services);
            AppSetting.Register(services, configuration);
            AddFilters(services);
            AddCustomResultFilter(services);
            AddDbContext(services);
            AddAutoMapper(services);
            AddRabbitMQ(services);
            AddSwagger.Register(services);
            AddAuthentication.Register(services); ;
            AddNewtonsoftJson(services);
            AddMemoryCache(services);
            return services;
        }
        //HttpContext对象注册
        private static void AddHttpContext(IServiceCollection services)
        {
            services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
        }
        //HttpContext对象注册
        private static void AddUserContext(IServiceCollection services)
        {
            services.AddSingleton<UserContext>();
        }
        /// <summary>
        /// 过滤器
        /// </summary>
        /// <param name="services"></param>
        public static void AddFilters(IServiceCollection services)
        {


            services.AddMvc(options =>
            {
                options.Filters.Add(typeof(ApiAuthorizeFilter));
            });
        }
        /// <summary>
        /// 配置跨域
        /// </summary>
        /// <param name="services"></param>
        private static void AddCors(IServiceCollection services) {
            services.AddCors(c=>
                  c.AddPolicy("any",
                        policy =>
                        {
                            policy
                            .SetIsOriginAllowed((host) => true)
                            .AllowAnyMethod()
                            .AllowAnyHeader()
                            .AllowCredentials();
                        })
               );
        }

        /// <summary>
        /// 模型验证
        /// </summary>
        private static void AddCustomResultFilter(IServiceCollection services)
        {
            ModelStateFilter.Register(services);
        }
        //实体映射注册
        private static void AddAutoMapper(IServiceCollection services)
        {
            AutoMapper.IConfigurationProvider config = new MapperConfiguration(cfg =>
            {
                cfg.AddProfile<AutoMapperProfile>();
            });
            services.AddSingleton(config);
            services.AddScoped<IMapper, Mapper>();
        }
        //EF实体容器注册
        private static void AddDbContext(IServiceCollection services)
        {
            services.AddDbContext<EfDbContext>(ServiceLifetime.Singleton, ServiceLifetime.Singleton);
        }

        /// <summary>
        /// 注入RabbitMQ.IBus实例对象
        /// </summary>
        /// <param name="services"></param>
        private static void AddRabbitMQ(IServiceCollection services)
        {
            //是否启用RedisMQ
            if (AppSetting.UseRabbitMQ)
            {
                string assemblyName = typeof(IMQEventBus).GetTypeInfo().Assembly.GetName().Name;
                services.AddRabbitMQEventBus(() => AppSetting.MQConnectionString, eventBusOptionAction: eventBusOption =>
                {
                    eventBusOption.ClientProvidedAssembly(assemblyName);
                    eventBusOption.EnableRetryOnFailure(true, 5000, TimeSpan.FromSeconds(30));
                    eventBusOption.RetryOnFailure(TimeSpan.FromSeconds(1));
                });
            }
            else {
                services.AddRedisMQEventBus();
            }
        }
        /// <summary>
        /// 配置Json格式
        /// </summary>
        /// <param name="services"></param>
        private static void AddNewtonsoftJson(IServiceCollection services)
        {
            services.AddControllers().AddNewtonsoftJson(options =>
            {
                // 忽略循环引用
                options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
                // 设置时间格式
                options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
                // 取消强制首字母小写
                options.SerializerSettings.ContractResolver = new DefaultContractResolver();
            });
            services.AddControllers().AddJsonOptions(options =>
            {
                //入参取消首字母强制小写
                options.JsonSerializerOptions.PropertyNamingPolicy = null;
            });

        }


        /// <summary>
        /// 注册内存缓存服务
        /// </summary>
        /// <param name="services"></param>
        private static void AddMemoryCache(IServiceCollection services)
        {
            services.AddMemoryCache();
        }
    }
}
